package cc.w3d.jawos.apps.artiks.manager.server;

import static cc.w3d.jawos.fangs.xresourceParameters.xresourceParameters.XResourceParametersContainer.XResourceParameters;
import static cc.w3d.jawos.fangs.xresources.xresources.XResourcesContainer.XResources;
import static cc.w3d.jawos.jinn.xjawosdata.xjawosdata.XJawosDataContainer.XJawosData;
import static cc.w3d.jawos.jinn.xuid.xuidGenerator.XUidGeneratorContainer.XUidGenerator;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import cc.w3d.jawos.apps.artiks.manager.client.beans.Article;
import cc.w3d.jawos.apps.artiks.manager.client.beans.ResourceItem;
import cc.w3d.jawos.apps.artiks.manager.client.beans.ResourceType;
import cc.w3d.jawos.apps.artiks.manager.client.rpc.ArtiksManagerService;
import cc.w3d.jawos.fangs.xresourceParameters.xresourceParameters.engines.xeDirectResourceParameters.configurationManager.XEDirectResourceParametersConfigurator;
import cc.w3d.jawos.fangs.xresources.xresources.core.Resource;
import cc.w3d.jawos.fangs.xresources.xresources.engines.xeDataResources.configurationManager.XEDataResourcesConfigurator;
import cc.w3d.jawos.jinn.xdata.xdata.engine.structure.RowData;
import cc.w3d.jawos.jinn.xjawosdata.xjawosdata.core.structure.JawosRowMapper;
import cc.w3d.jawos.jinn.xjawosdata.xjawosdata.engine.structure.JawosRowData;
import cc.w3d.jawos.jinn.xjawosdata.xjawosdata.engines.xeMysqlJawosData.configurationManager.XEMysqlJawosDataConfigurator;
import cc.w3d.jawos.jinn.xuid.xuidGenerator.core.structure.Uid;
import cc.w3d.jawos.tools.global.configurationLoader.Configuration;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class ArtiksManagerServiceImpl extends RemoteServiceServlet implements ArtiksManagerService
{
	private static final long serialVersionUID = -4053478076933295160L;

	private static final String RESOURCE_NAME_PARAMETER    = "ResourceName";
	private static final String ARTICLE_BODY_PARAMETER     = "ArticleBody";
	private static final String ARTICLE_TITLE_PARAMETER    = "ArticleTitle";
	private static final String ARTICLE_SUBTITLE_PARAMETER = "ArticleSubtitle";
	private static final String ARTICLE_DATE_PARAMETER     = "ArticleDate";
	private static final String ARTICLE_IMG_PARAMETER      = "ArticleImg";
	private static final String ARTICLE_INTRO_PARAMETER    = "ArticleIntro";
	private static final String ARTICLE_CAT_PARAMETER      = "ArticleCat";

	public ArtiksManagerServiceImpl()
	{
		super();
		initializeMySqlDbConfig();
	}

	public static void initializeMySqlDbConfig()
	{
		XEMysqlJawosDataConfigurator cfg = (XEMysqlJawosDataConfigurator)XJawosData.getEngineConfigurationManager();
		Configuration.configure(cfg);

		XEDataResourcesConfigurator rcfg = 
			(XEDataResourcesConfigurator)XResources.getEngineConfigurationManager();

		rcfg.setReference("XRESOURCES");

		XEDirectResourceParametersConfigurator rpcfg = 
			(XEDirectResourceParametersConfigurator)XResourceParameters.getEngineConfigurationManager();

		rpcfg.setReference("XRESOURCESPARAMETERS");

		if(!tableCreated())
			XJawosData.update("create table Article (id BIGINT, titol TEXT, subtitol TEXT, body TEXT, date BIGINT, img VARCHAR(255), intro TEXT, PRIMARY KEY(id))");

		if(!tableCreated("XRESOURCES_Resource"))
			rcfg.format();

		if(!tableCreated("XRESOURCESPARAMETERS_Index"))
			rpcfg.format();
	}

	private static boolean tableCreated() //throws Exception
	{
		List<Map<String, Object>> results = XJawosData.query("show tables where Tables_in_" + Configuration.getMySqlTestDatabaseName() + " = 'Article'");
		
		return results.size() > 0;
	}

	private static boolean tableCreated(String tableName) //throws Exception
	{
		List<Map<String, Object>> results = XJawosData.query("show tables where Tables_in_" + Configuration.getMySqlTestDatabaseName() + " = '" + tableName + "'");
		
		return results.size() > 0;
	}

	public List<ResourceItem> getChilds(String id)
	{
		Resource root = id == null ? XResources.root() : XResources.getResourceById(XUidGenerator.recover(id));
		List<ResourceItem> r = new ArrayList<ResourceItem>();

		for (Resource item : root.getChilds())
		{
			Integer typeId = item.getType();
			if(typeId == null) continue;

			ResourceType type = ResourceType.getFromTypeId(typeId);
			if(type == null) continue;

			String name = XResourceParameters.get(item).get(RESOURCE_NAME_PARAMETER);
			if(name == null) name = "";

			ResourceItem ritem = new ResourceItem();
			ritem.id = item.getId().toString();
			ritem.type = type;
			ritem.name = name;

			r.add(ritem);
		}

		return r;
	}

	public ResourceItem addChild(String parentResourceId, ResourceType type, String name)
	{
		Resource root = parentResourceId == null ? XResources.root() : XResources.getResourceById(XUidGenerator.recover(parentResourceId));
		Resource newChild = root.addChild(type.toInt());
		Date date = new Date();
		XResourceParameters.get(newChild).put(RESOURCE_NAME_PARAMETER, name);
		XResourceParameters.get(newChild).put(ARTICLE_DATE_PARAMETER, date.getTime() + "");

		ResourceItem item = new ResourceItem();

		item.id = newChild.getId().toString();
		item.type = type;
		item.name = name;

		if(type == ResourceType.ARTICLE)
		{
			Article art = new Article();
	
			art.id       = newChild.getId().toLong();
			art.stringId = newChild.getId().toString();
			art.titol    = name;
			art.subtitol = "";
			art.body     = "";
			art.date     = date;
			art.img      = "";
			art.intro    = "";
			art.cat      = null;

			XJawosData.objectInsert(art);
		}

		return item;
	}

	public void removeItem(String itemId)
	{
		Resource item = itemId == null ? XResources.root() : XResources.getResourceById(XUidGenerator.recover(itemId));

		item.remove();
		Article art = new Article();

		art.id = XUidGenerator.recover(itemId).toLong();
		XJawosData.objectDelete(art);
	}

	public Article getArticle(String itemId)
	{
		if(itemId == null)
			throw new RuntimeException("Missing resource item id");

		Article  r     = new Article();
		Resource root  = XResources.getResourceById(XUidGenerator.recover(itemId));

		String   name     = XResourceParameters.get(root).get(RESOURCE_NAME_PARAMETER);
		String   title    = XResourceParameters.get(root).get(ARTICLE_TITLE_PARAMETER);
		String   subtitle = XResourceParameters.get(root).get(ARTICLE_SUBTITLE_PARAMETER);
		String   body     = XResourceParameters.get(root).get(ARTICLE_BODY_PARAMETER);
		Date     date     = new Date(new Long(XResourceParameters.get(root).get(ARTICLE_DATE_PARAMETER)).longValue());
		String   img      = XResourceParameters.get(root).get(ARTICLE_IMG_PARAMETER);
		String   intro    = XResourceParameters.get(root).get(ARTICLE_INTRO_PARAMETER);
		String   cat      = XResourceParameters.get(root).get(ARTICLE_CAT_PARAMETER);

		r.id       = XUidGenerator.recover(itemId).toLong();
		r.stringId = XUidGenerator.recover(itemId).toString();
		r.titol    = title == null ? name : title;
		r.subtitol = subtitle == null ? "" : subtitle;
		r.body     = body == null ? "" : body;
		r.date     = date;
		r.img      = img;
		r.intro    = intro;
		r.cat      = cat == null ? null : new Integer(cat);

		return r;
	}

	public void setArticle(String itemId, Article article)
	{
		if(itemId == null)
			throw new RuntimeException("Missing resource item id");

		Resource root = XResources.getResourceById(XUidGenerator.recover(itemId));

		XResourceParameters.get(root).put(ARTICLE_DATE_PARAMETER,     article.date.getTime() + "");
		XResourceParameters.get(root).put(ARTICLE_TITLE_PARAMETER,    article.titol);
		XResourceParameters.get(root).put(ARTICLE_SUBTITLE_PARAMETER, article.subtitol);
		XResourceParameters.get(root).put(ARTICLE_BODY_PARAMETER,     article.body);
		XResourceParameters.get(root).put(ARTICLE_IMG_PARAMETER,      article.img);
		XResourceParameters.get(root).put(ARTICLE_INTRO_PARAMETER,    article.intro);
		XResourceParameters.get(root).put(ARTICLE_CAT_PARAMETER,      article.cat + "");

		article.id = XUidGenerator.recover(itemId).toLong();

		XJawosData.objectUpdate(article);
	}

	public List<Article> getArticles(int n)
	{
		String limit = n == -1 ? "" : " limit 0," + n + " ";
		String orderby = " order by date desc ";

		String query = "SELECT * FROM Article WHERE date < " + System.currentTimeMillis() + orderby + limit;
		System.out.println("query: " + query);
		return XJawosData.query(query, new JawosRowMapper<Article>()
		{

			@Override
			public Article map(JawosRowData row)
			{
				Article r = new Article();

				r.stringId =          getUid    (row, "id"      ).toString();

				return r;
			}

			long   getLong   (     RowData row, String field) {try{return row.getLong   (field);}catch(Exception e){return 0;}}
			String getString (     RowData row, String field) {try{return row.getString (field);}catch(Exception e){return null;}}
			Uid    getUid    (JawosRowData row, String field) {try{return row.getUid    (field);}catch(Exception e){return null;}}

			@Override
			public Article map(RowData row)
			{
				Article r = new Article();

				if(row instanceof JawosRowData)
					r = map((JawosRowData)row);
				else
					r.stringId = XUidGenerator.recover(getLong   (row, "id")).toString();

				r.id       =          getLong   (row, "id"      );
				r.titol    =          getString (row, "titol"   );
				r.subtitol =          getString (row, "subtitol");
				r.body     =          getString (row, "body"    );
				r.date     = new Date(getLong   (row, "date"    ));
				r.img      =          getString (row, "img"     );
				r.intro    =          getString (row, "intro"   );

				return r;
			}
		});
	}

	@Override
	public int countArticles()
	{
		String orderby = " order by date desc ";

		String query = "SELECT COUNT(*) AS result FROM Article WHERE date < " + System.currentTimeMillis() + orderby;
		System.out.println("query: " + query);

		return (Integer)(XJawosData.query(query).get(0).get("result"));
	}
}
